 package com.htdata.iiot;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.htdata.iiot.db.DbConnectionPool;

public class Main {
	private static DbConnectionPool pool = DbConnectionPool.getPool();

	public static void main(String[] args) throws IOException {
		int tid = -1;
		String dev = null;
		String metricPath = null;
		if(args.length!=3){
			System.err.println("参数不正确");
			System.exit(0);
		}
		for(String arg:args){
			String[] split = arg.split("=");
			switch (split[0]) {
			case "tid":
				tid = Integer.parseInt(split[1]);
				break;
			case "dev":
				dev = split[1];
				break;
			case "metric":
				metricPath = split[1];
				break;

			default:
				break;
			}
		}
		if(tid==-1){
			System.err.println("tid参数未设置");
			System.exit(0);
		}
		
		if(dev==null||"".equals(dev)){
			System.err.println("dev参数未设置");
			System.exit(0);
		}
		
		if(metricPath==null||"".equals(metricPath)){
			System.err.println("metric参数未设置");
			System.exit(0);
		}
		
		
		//1.创建设备模板
		int devId = getDevId(dev, tid);
		if(devId>=0){
			System.err.println("该模板或设备已存在");
			System.exit(0);
		}
		insertDev(dev, tid);
		System.out.println("设备模板已创建");
		//2.获取设备模板ID
		devId = getDevId(dev, tid);
		System.out.println("设备模板ID:"+devId);
		//3.解析测点文件
		Map<String, String> parserFile = parserFile(metricPath);
		//4.创建测点
		insertMetric(devId,tid, parserFile);
		System.out.println("测点已创建");
		Map<String, Integer> metricMap = getMetric(tid, parserFile);
		//5.创建数据流
		insertStream(tid, parserFile, metricMap);
		System.out.println("数据流已创建");
		//6.创建设备与数据流对应关系
		insertDevicePoint(devId, metricMap);
		System.out.println("对应关系已创建");
		
	}
	
	public static void insertDev(String name,int tid){
		String sql1 = "insert into thing_device(struct_id,name,parent_id,group_id,tenant_id,deleted,status,type) "
				+ "values(0,?,0,0,?,0,0,1)";
		Connection conn = pool.getConnection();
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql1);
			ps.setString(1, name);
			ps.setInt(2, tid);
			ps.addBatch();
			ps.executeBatch();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static int getDevId(String name,int tid){
		String sql1 = "select id from thing_device where name=? and tenant_id=?";
		Connection conn = pool.getConnection();
		PreparedStatement ps = null;
		int did=-1;
		try {
			ps = conn.prepareStatement(sql1);
			ps.setString(1, name);
			ps.setInt(2, tid);
			ResultSet executeQuery = ps.executeQuery();
			while(executeQuery.next()){
				did =  executeQuery.getInt("id");
				break;
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		return did;
	}
	
	public static Map<String, String> parserFile(String fileName) throws IOException{
		Reader in = new FileReader(fileName);
		BufferedReader reader = new BufferedReader(in);
		String line = null;
		Map<String, String> metricMap = new HashMap<>();
		while((line = reader.readLine())!=null){
			String[] split = line.split(",");
			if(split.length!=2){
				continue;
			}
			metricMap.put(split[0].trim(), split[1].trim());
		}
		return metricMap;
		
		
	}

	public static void insertMetric(int did,int tid,Map<String, String> map){
		String sql1 = "insert into thing_component(struct_id,name,tenant_id,deleted,status,public) "
				+ "values(?,?,?,0,0,0)";
		Connection conn = pool.getConnection();
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql1);
			
			Set<String> keySet = map.keySet();
			for(String key:keySet){
				ps.setInt(1, did);
				ps.setString(2, key);
				ps.setInt(3, tid);
				ps.addBatch();
			}
			ps.executeBatch();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static Map<String, Integer> getMetric(int tid,Map<String, String> map){
		String sql1 = "select id,name from thing_component where tenant_id=? and  name in (";
		Connection conn = pool.getConnection();
		PreparedStatement ps = null;
		Map<String, Integer> resultMap = new HashMap<>();
		try {
			Set<String> keySet = map.keySet();
			StringBuffer buffer =new StringBuffer();
			for(String key:keySet){
				buffer.append(",'").append(key).append("'");
			}
			sql1 = sql1+buffer.substring(1)+")";
			ps = conn.prepareStatement(sql1);
			ps.setInt(1, tid);
			ResultSet executeQuery = ps.executeQuery();
			
			while(executeQuery.next()){
				resultMap.put(executeQuery.getString("name"), executeQuery.getInt("id"));
			}
			
		}catch (Exception e) {
			e.printStackTrace();
		}
		return resultMap;
	}
	
	public static void insertStream(int tid,Map<String, String> Dpmap,Map<String, Integer> metricMap){
		String sql1 = "insert into thing_data_stream(name,tenant_id,deleted,status,component_id) "
				+ "values(?,?,0,0,?)";
		Connection conn = pool.getConnection();
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql1);
			
			Set<String> keySet = Dpmap.keySet();
			for(String key:keySet){
				ps.setString(1, Dpmap.get(key));
				ps.setInt(2, tid);
				ps.setInt(3, metricMap.get(key));
				ps.addBatch();
			}
			ps.executeBatch();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void insertDevicePoint(int deviceId,Map<String, Integer> metricMap){
		String sql1 = "insert into thing_device_component_rel(device_id,deleted,status,component_id) "
				+ "values(?,0,0,?)";
		Connection conn = pool.getConnection();
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql1);
			
			Collection<Integer> values = metricMap.values();
			for(Integer value:values){
				ps.setInt(1, deviceId);
				ps.setInt(2, value);
				ps.addBatch();
			}
			ps.executeBatch();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}

}
